/*
 * dump_manager.c
 *
 *  Created on: Mar 14, 2014
 *      Author: lifeng
 */

#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <dirent.h>
#include <unistd.h>
#include <sys/mount.h>
#include <sys/time.h>
#include <time.h>
#include <errno.h>

#include "dump.h"
#include "dump_manager.h"

#include "../storage/record_manager.h"

#include "../lib/block_manager.h"
#include "../lib/block_filter.h"

#include "../led/led.h"
#include "../config/config.h"

#include "../lib/hwclock.h"
#include "../WatchDog/WatchDog.h"

#include "../sound/sound.h"

#define DATE_ITEM_SIZE	(16)

#ifdef __x86_64
const char NAME_PREFIX[] = "sdb"; //模拟机
#else
const char NAME_PREFIX[] = "sd"; //实际ARM开发板
#endif

const char MOUNT_POINT[] = "/mnt";

const char KEY_BEGINTIME[] = "BeginTime=";
const char KEY_ENDTIME[] = "EndTime=";
const char COPY_ALL[] = "CopyAll=y";
const char COPY_ALL1[] = "CopyAll=1";
const char COPY_ALL2[] = "CopyAll=2";
const char COPY_ALL3[] = "CopyAll=3";
const char COPY_ALL4[] = "CopyAll=4";
const char COPY_ALL5[] = "CopyAll=5";
const char COPY_ALL6[] = "CopyAll=6";
const char COPY_ALL7[] = "CopyAll=7";
const char COPY_ALL8[] = "CopyAll=8";
const char COPY_ALL9[] = "CopyAll=9";
const char COPY_ALL10[] = "CopyAll=10";
const char COPY_ALL11[] = "CopyAll=11";
const char COPY_ALL12[] = "CopyAll=12";
const char COPY_ALL13[] = "CopyAll=13";
const char COPY_ALL14[] = "CopyAll=14";
const char COPY_ALL15[] = "CopyAll=15";
const char COPY_ALL32[] = "CopyAll=32";
const char COPY_ALLa[] = "CopyAll=a";
const int COPY_PAGE_SIZE = 1024 * 1024;
static struct dump_manager* gpdump_manager = NULL;

static void * get_extern_device() {

	static char device_name[50];

	char buffer[200];
	char name[20];
	int length;
	int i, j;
	int next_space;
	int segment_index = 0;
	int major = 0;
	//int minor = 0;

	memset(name, 0, sizeof(name));
	FILE* file = fopen("/proc/partitions", "r");
	if (file == NULL)
		return NULL;

	while (fgets(buffer, sizeof(buffer), file)) {

		length = strlen(buffer);
		if (length <= 5)
			continue;
		major = 0;
		//minor = 0;
		segment_index = 0;
		for (i = 0; i < length; i++) {
			if (isspace(buffer[i]))
				continue;
			next_space = i + 1;
			for (j = i + 1; j < length; j++) {
				if (isspace(buffer[j])) {
					buffer[j] = '\0';
					break;
				}
				next_space = j + 1;
			}
			switch (segment_index) {
			case 0:
				major = atoi(buffer + i);
				break;
			case 1:
				//minor = atoi(buffer + i);
				break;
			case 2:
				//#block num
				break;
			case 3:
				if (strncmp(buffer + i, NAME_PREFIX, sizeof(NAME_PREFIX) - 1)
						== 0) {
					strncpy(name, buffer + i, next_space - i);
				}

				break;
			}
			if (major != 8)
				break;
			i = next_space;
			segment_index++;
		}

	}

	fclose(file);

	length = strlen(name);
	if (length < 3) {
		return NULL;
	}
	sprintf(device_name, "/dev/%s", name);

	return device_name;
}

static void wait_usb_plugout(struct dump_manager *manager) {
	char *device = NULL;

	while (1) {

		device = get_extern_device();
		if (device == NULL)
			break;
		sleep(1);

	}
}

static void wait_usb_plugin(struct dump_manager *manager) {
	char *device = NULL;

	while (1) {

		device = get_extern_device();
		if (device == NULL) {
			memset(manager->device_name, 0, 50);
			manager->device_exit_time = 0;
		} else {
			if (strcmp(manager->device_name, device) == 0) {
				manager->device_exit_time = manager->device_exit_time + 1;
			} else {
				manager->device_exit_time = 1;
				strcpy(manager->device_name, device);
			}

		}
		if (manager->device_exit_time == 3) {
			break;
		}

		sleep(1);
	}
}

static int mount_usb(struct dump_manager *manager) {
	char * device = manager->device_name;
	//返回0。失败返回-1
	int ret = mount(device, MOUNT_POINT, "vfat", 0, NULL);
	printf("device_name=%s\r\n", manager->device_name);
	printf("ret=%d\r\n", ret);
	return ret;
}

static void unmount_usb(struct dump_manager *manager) {

	umount(MOUNT_POINT);
	umount(MOUNT_POINT);
}

static int exe_update(struct dump_manager * manager) {
	char file_update[50];

	char file_name[50];
	sprintf(file_update, "sh %s/update", MOUNT_POINT);
	sprintf(file_name, "%s/update", MOUNT_POINT);
	if (access(file_name, F_OK) != 0) {
		printf("%s no exist\r\n", file_name);
		return -1;

	}

	system(file_update);
	return 0;
}

static int get_config_info(struct dump_manager *manager) {
	FILE * file = NULL;
	char file_name[50];
	char buffer[100];
	char tmpbuf[100];
	int i, j;

	struct timeval tv;
//	struct tm* ptm;
	int year, month, day;
//	time_t beginTime;
//	time_t endTime;
	gettimeofday(&tv, NULL);
//	endTime = tv.tv_sec;
	manager->acordding_time = 0;
	manager->copy_all = 0;
	manager->begin_time = 0;
	manager->end_time = (99 << 16) | (12 << 8) | (31); //2099-12-31
	sprintf(file_name, "%s/config.ini", MOUNT_POINT);
	file = fopen(file_name, "r");
	if (file != NULL) {
		manager->acordding_time = 1; //根据时间拷贝数据
		while (fgets(buffer, sizeof(buffer), file)) {
			year = -1;
			month = -1;
			day = -1;
			if(tmpbuf[0] == '\n' || tmpbuf[0] == '\r')
            {
                continue;   //处理空行
            }

//			j=0;
//			for(i=0; i < strlen(tmpbuf); i++){
//                if(tmpbuf[i] != ' '){
//                    buffer[j] = tmpbuf[i];
//                    j++;
//                }
//			}
//			buffer[j+1] = '\0';

			if (strncmp(buffer, KEY_BEGINTIME, strlen(KEY_BEGINTIME)) == 0) { //开始时间
				sscanf(buffer, "BeginTime=%d-%d-%d", &year, &month, &day);
				if (year >= 2000 && month > 0 && day > 0) {
					manager->begin_time = ((year - 2000) << 16) | (month << 8)
							| (day);
				}
			} else if (strncmp(buffer, KEY_ENDTIME, strlen(KEY_ENDTIME)) == 0) { //结束时间
				sscanf(buffer, "EndTime=%d-%d-%d", &year, &month, &day);
				if (year >= 2000 && month > 0 && day > 0) {
					manager->end_time = ((year - 2000) << 16) | (month << 8)
							| (day);
				}
			} else if (strlen(buffer) == strlen(COPY_ALL) && strncmp(buffer, COPY_ALL, strlen(COPY_ALL)) == 0) {
			//if (strlen(buffer) == strlen(COPY_ALL) && strncmp(buffer, COPY_ALL, strlen(COPY_ALL)) == 0) {
                manager->copy_all = 1;
                manager->copy_day_count=7;
            } else if (strlen(buffer) == strlen(COPY_ALLa) && strncmp(buffer, COPY_ALLa, strlen(COPY_ALLa)) == 0) {  //增量拷贝
                manager->acordding_time = 0;
            } else if (strlen(buffer) == strlen(COPY_ALL10) && strncmp(buffer, COPY_ALL10, strlen(COPY_ALL10)) == 0) {
                manager->copy_all = 1;
                manager->copy_day_count=11;
            } else if (strlen(buffer) == strlen(COPY_ALL15) && strncmp(buffer, COPY_ALL15, strlen(COPY_ALL15)) == 0) {
                manager->copy_all = 1;
                manager->copy_day_count=16;
			} else if (strlen(buffer) == strlen(COPY_ALL1) && strncmp(buffer, COPY_ALL1, strlen(COPY_ALL1)) == 0) {
				manager->copy_all = 1;
				manager->copy_day_count=2;
			} else if (strlen(buffer) == strlen(COPY_ALL2) && strncmp(buffer, COPY_ALL2, strlen(COPY_ALL2)) == 0) {
				manager->copy_all = 1;
				manager->copy_day_count=3;
			} else if (strlen(buffer) == strlen(COPY_ALL3) && strncmp(buffer, COPY_ALL3, strlen(COPY_ALL3)) == 0) {
				manager->copy_all = 1;
			    manager->copy_day_count=4;
			} else if (strlen(buffer) == strlen(COPY_ALL4) && strncmp(buffer, COPY_ALL4, strlen(COPY_ALL4)) == 0) {
				manager->copy_all = 1;
				manager->copy_day_count=5;
			} else if (strlen(buffer) == strlen(COPY_ALL5) && strncmp(buffer, COPY_ALL5, strlen(COPY_ALL5)) == 0) {
				manager->copy_all = 1;
				manager->copy_day_count=6;
			} else if (strlen(buffer) == strlen(COPY_ALL6) && strncmp(buffer, COPY_ALL6, strlen(COPY_ALL6)) == 0) {
				manager->copy_all = 1;
				manager->copy_day_count=7;
			} else if (strlen(buffer) == strlen(COPY_ALL7) && strncmp(buffer, COPY_ALL7, strlen(COPY_ALL7)) == 0) {
				manager->copy_all = 1;
				manager->copy_day_count=8;
			} else if (strlen(buffer) == strlen(COPY_ALL8) && strncmp(buffer, COPY_ALL8, strlen(COPY_ALL8)) == 0) {
				manager->copy_all = 1;
				manager->copy_day_count=9;
			} else if (strlen(buffer) == strlen(COPY_ALL9) && strncmp(buffer, COPY_ALL9, strlen(COPY_ALL9)) == 0) {
				manager->copy_all = 1;
				manager->copy_day_count=10;
            } else if (strlen(buffer) == strlen(COPY_ALL10) && strncmp(buffer, COPY_ALL10, strlen(COPY_ALL10)) == 0) {
                manager->copy_all = 1;
                manager->copy_day_count=11;
            } else if (strlen(buffer) == strlen(COPY_ALL11) && strncmp(buffer, COPY_ALL11, strlen(COPY_ALL11)) == 0) {
                manager->copy_all = 1;
                manager->copy_day_count=12;
            } else if (strlen(buffer) == strlen(COPY_ALL12) && strncmp(buffer, COPY_ALL12, strlen(COPY_ALL12)) == 0) {
                manager->copy_all = 1;
                manager->copy_day_count=13;
            } else if (strlen(buffer) == strlen(COPY_ALL13) && strncmp(buffer, COPY_ALL13, strlen(COPY_ALL13)) == 0) {
                manager->copy_all = 1;
                manager->copy_day_count=14;
            } else if (strlen(buffer) == strlen(COPY_ALL14) && strncmp(buffer, COPY_ALL14, strlen(COPY_ALL14)) == 0) {
                manager->copy_all = 1;
                manager->copy_day_count=15;
			} else {
                manager->copy_all = 1;
                manager->copy_day_count=7;
			}
		}

		fclose(file);
	}
	else
    {
        manager->copy_all = 1;
        manager->copy_day_count=7;
    }
	return 0;
}

static int mk_dir(char *dir) {
	DIR *mydir = NULL;
	if ((mydir = opendir(dir)) == NULL) {
		int ret = mkdir(dir, 0755);
		if (ret != 0) {
			return -1;
		}
	} else {
		closedir(mydir);
	}
	return 0;
}

int getDatePos(int date_pos, int data_size, struct CSection* currentSection) {
	date_pos = (currentSection->date_next_off + currentSection->date_total
			- data_size) % (currentSection->date_total);
	return date_pos;
}

int GetCopyRecList(int section, int * size_list, int * offset_list,
		struct record_manager* record_manager, struct dump_manager* manager) {
	int i = 0;
	int list_cnt = 0;
	int size;
	int offset;
	int date_pos;
	int cur_date;

	struct CSection *currentSection =
			&(record_manager->dics[0].sections[section]);
	const __int64_t total = (currentSection->total);
	int day_count = record_manager->dics[0].sections[section].date_size;
	if (manager->copy_all) //拷贝最近N天
	{
	        printf("copy_all acordding_time=%d\r\n", manager->acordding_time);

		if (day_count > manager->copy_day_count * DATE_ITEM_SIZE) {
			day_count = manager->copy_day_count * DATE_ITEM_SIZE;
		}

		while (day_count > 0) {
			date_pos = getDatePos(date_pos, day_count, currentSection);
			cur_date = record_manager->date_tbl[section][date_pos / 4];
			size = record_manager->date_tbl[section][date_pos / 4 + 1];
			if (size > total)
				size = total;
			offset = record_manager->date_tbl[section][date_pos / 4 + 2];
			//offset -= size;
			size_list[i] = size;
			offset_list[i] = offset;
			list_cnt++;
			i++;

            printf("date-----%02x-%02x-%02x  size = %10d  offset=%10d next_off=%10d\n\r", cur_date, manager->begin_time,
                    manager->end_time,size,offset,size+offset);
			if (i >= 32)
				break;

			day_count -= DATE_ITEM_SIZE;
		}
	} else if (manager->acordding_time) //根据时间列表
	{
		printf("copy_acordding_time\r\n");

		i = 0;
		while (day_count > 0) {
			date_pos = getDatePos(date_pos, day_count, currentSection);
			cur_date = record_manager->date_tbl[section][date_pos / 4];

			if ((cur_date >= manager->begin_time)
					&& (cur_date <= manager->end_time)) {
				size = record_manager->date_tbl[section][date_pos / 4 + 1];
				if (size > total)
					size = total;

				offset = record_manager->date_tbl[section][date_pos / 4 + 2];
				//offset -= size;
				size_list[i] = size;
				offset_list[i] = offset;
				list_cnt++;
				i++;

                printf("date-----%02x-%02x-%02x  size = %10d  offset=%10d next_off=%10d\n\r", cur_date, manager->begin_time,
                        manager->end_time,size,offset,size+offset);
				if (i >= 32)
					break;
			}
			day_count -= DATE_ITEM_SIZE;
		}
	} else //最近拷贝
	{
	        printf("Recent copy!\r\n");
		size = record_manager->dics[0].sections[section].last_size;
		if (size > total)
			size = total;

		offset = record_manager->dics[0].sections[section].last_next_off;
		offset = (offset + total - size) % total;
		size_list[0] = size;
		offset_list[0] = offset;
		list_cnt = 1;

        printf("date-----%x-%x  size=%10d  offset=%10d next_off=%10d\n\r", manager->begin_time,
                manager->end_time,size,offset,size+offset);
	}
	return list_cnt;
}

void GetDumpFileFullPath(char * buffer, int section, const char *MOUNT_POINT,
		struct tm * tNow, char * locomotiveId) {
	char buffer1[256];
	if (mk_dir(buffer) == 0) {
		sprintf(buffer1, "%s/%04d-%02d-%02d %02d,%02d,%02d/", buffer,
				tNow->tm_year + 1900, tNow->tm_mon + 1, tNow->tm_mday,
				tNow->tm_hour, tNow->tm_min, tNow->tm_sec);
		if (mk_dir(buffer1) == 0) {
			switch (section) {
			case 0:
				sprintf(buffer, "%s/Menu.bin", buffer1);
				break;
			case 1:
				sprintf(buffer, "%s/Data.bin", buffer1);
				break;
			case 2:
				sprintf(buffer, "%s/Wave.bin", buffer1);
				break;
            case 3:
                sprintf(buffer, "%s/Info.bin", buffer1);
                break;
			}
		} else {
			switch (section) {
			case 0:
				sprintf(buffer, "%s/%s/Menu.bin", MOUNT_POINT, locomotiveId);
				break;
			case 1:
				sprintf(buffer, "%s/%s/Data.bin", MOUNT_POINT, locomotiveId);
				break;
			case 2:
				sprintf(buffer, "%s/%s/Wave.bin", MOUNT_POINT, locomotiveId);
				break;
            case 3:
                sprintf(buffer, "%s/%s/Info.bin", MOUNT_POINT, locomotiveId);
                break;
			}
		}
	} else {
		switch (section) {
		case 0:
			sprintf(buffer, "%s/Menu.bin", MOUNT_POINT);
			break;
		case 1:
			sprintf(buffer, "%s/Data.bin", MOUNT_POINT);
			break;
		case 2:
			sprintf(buffer, "%s/Wave.bin", MOUNT_POINT);
			break;
        case 3:
            sprintf(buffer, "%s/Info.bin", MOUNT_POINT);
            break;
		}
	}
}
static int dump_read(char* data,size_t size,FILE *file,size_t section_size, size_t section_start,size_t readPosInSection)
{
    readPosInSection %= section_size;
    fseek(file, section_start+readPosInSection, SEEK_SET);
    int read_size=size<(section_size-readPosInSection)?size:(section_size-readPosInSection);
    int read_count=fread(data, read_size, 1, file);

    if(read_count==size) {
            return read_count;
    }   else     {
            return dump_read(data+read_count,size-read_size,file,section_size,section_start,0)+read_count;
    }
}
static int dump_data(struct dump_manager *manager, int section) {
	char buffer[256];
	char log_buffer[256];
	char dump_buffer[COPY_PAGE_SIZE];
	FILE * file = NULL;
	FILE * fInfo = NULL;
	int i = 0, j, k;
	int result = 0;

	extern int errno;

	int size, offset, size1, rd_size,size2;
	int size_list[32] ={0};
	int offset_list[32]={0};
	int list_cnt = 0;
	__int64_t tempOffset = 0;

	char info_buf[256];
    char info[1] = "v";
	int tmp[256];
	struct CSection *currentSection;
	struct record_manager * record_manager = get_record_manager();
	currentSection = &(record_manager->dics[0].sections[section]);

	if (section < 0 || section > 2) {
		printf("Section==%d", section);
		return -1;
	}
	sprintf(buffer, "%s/%s/", MOUNT_POINT, manager->ID);
	sprintf(info_buf, "%s/%s/", MOUNT_POINT, manager->ID);
	GetDumpFileFullPath(buffer, section, MOUNT_POINT, &(manager->time_export),
			manager->ID);
    GetDumpFileFullPath(info_buf, 3, MOUNT_POINT, &(manager->time_export),
            manager->ID);
	const __int64_t total = (currentSection->total);
	list_cnt = GetCopyRecList(section, size_list, offset_list, record_manager,
			manager);

	printf("Create file %d!,list_cnt=%d\n", section,list_cnt);
	file = fopen(buffer, "w+");

	if (file == NULL) {
		printf("Create file err %d!\n", section);
		system("reboot\n");
		return -1;
	}

	set_disk_using(1);  // 转储锁定
	sleep(2);
	//sync();

	if(section == 0)
	{
        fInfo = fopen(info_buf, "w+");
        if (fInfo == NULL) {
            printf("Create fInfo err %d!\n", section);
            system("reboot\n");
            return -1;
        }
        fwrite(record_manager->dics, sizeof(record_manager->dics), 1, fInfo);
        fwrite(record_manager->date_tbl, sizeof(record_manager->date_tbl), 1, fInfo);

        printf("Writed Len = %ld\r\n", ftell(fInfo));
        result = fclose(fInfo);
        if (result != 0) {
            system("reboot\n");
            printf("fInfo err\r\n");
            return -1;
        }
	}
	else
    {
        fInfo = fopen(info_buf, "r+");
        if (fInfo == NULL) {
            printf("Create fInfo err %d!\n", section);
            system("reboot\n");
            return -1;
        }

        fseek(fInfo,1024*8, SEEK_END);
        fwrite(size_list, sizeof(size_list), 1, fInfo);
        fwrite(offset_list, sizeof(offset_list), 1, fInfo);
        //写入不压缩音频标志(因有损压缩导致CRCC失真)
        fwrite(info, sizeof(info), 1, fInfo);

        printf("Writed Len = %ld\r\n", ftell(fInfo));
        result = fclose(fInfo);
        if (result != 0) {
            system("reboot\n");
            printf("fInfo err\r\n");
            return -1;
        }
    }
    //pthread_mutex_lock(&(record_manager->mutex_FileOpt));
    //{
        for (j = 0; j < list_cnt; j++) {
            size = size_list[j];
            offset = offset_list[j];



            size1 = (size + offset) >= total?(total-offset):size;
            size2 = size-size1;

            if(size1 > 0){
                    tempOffset = offset + (currentSection->offset);
                    while (size1 > 0) {
                        //pthread_mutex_lock(&(record_manager->mutex_FileOpt));
                        //{
                            fseek(record_manager->file, tempOffset, SEEK_SET);
                            rd_size =size1 > COPY_PAGE_SIZE?COPY_PAGE_SIZE:size1;
                            fread(dump_buffer,rd_size,1,record_manager->file);
                            //printf("read offset=0x%x size1=%d rd_size=%d total=%ld\r\n", tempOffset, size1, rd_size, total);
                            tempOffset += rd_size;
                            //tempOffset %= total;
                        //}
                    //pthread_mutex_unlock(&(record_manager->mutex_FileOpt));

                    result = fwrite(dump_buffer, rd_size, 1, file);

                    if (result <= 0) {
                        printf("Mesg:%s\r\n", strerror(errno));
                        printf("write err\r\n");
                        system("reboot\n");
                    }
                    size1 -= rd_size;
                    i++;
                }
            }

            if(size2 > 0){
                printf("\r\n ------dump return point!------\r\n");

                tempOffset = (currentSection->offset);
                 while (size2 > 0) {
                 //pthread_mutex_lock(&(record_manager->mutex_FileOpt));
                 //{
                    fseek(record_manager->file, tempOffset, SEEK_SET);
                    //printf("read offset = 0x%x\r\n", tempOffset);
                    rd_size =size2 > COPY_PAGE_SIZE?COPY_PAGE_SIZE:size2;
                    fread(dump_buffer,rd_size,1,record_manager->file);
                    tempOffset += rd_size;
                    //tempOffset %= total;
                 //}
                 //pthread_mutex_unlock(&(record_manager->mutex_FileOpt));

                 result = fwrite(dump_buffer, rd_size, 1, file);
                 if (result <= 0) {
                        printf("Mesg:%s\r\n", strerror(errno));
                        printf("write err\r\n");
                        system("reboot\n");
                  }
                  size2 -= rd_size;
                  i++;
                }
              }

        }

    //pthread_mutex_unlock(&(record_manager->mutex_FileOpt));
	set_disk_using(0);

	result = fclose(file);
	if (result != 0) {
		system("reboot\n");
		printf("fsyush err\r\n");
		return -1;
	}

	record_manager->dics[0].sections[section].last_size = 0l;
	record_manager->dics[1].sections[section].last_size = 0l;

    struct record_dic* dic = record_manager->dics;
    dic->crc = compute_crc16(dic, 510);

    fseek(record_manager->file, 1024*8, SEEK_SET);
    fwrite(dic, 512, 1, record_manager->file);
    fflush(record_manager->file);
    fwrite(dic, 512, 1, record_manager->file);
    fflush(record_manager->file);
    //fsync(fileno(record_manager->file));


    printf("\r\n");
    //sync();
	return 0;

}

static void get_record_id(struct dump_manager *manager) {
	char *id = get_id();
	memcpy(manager->ID, id, 32);
}
void * dump_proc(void * args) {
	int result = 0;
	int i = 0;

	struct dump_manager *manager = (struct dump_manager*) args;
	while (1) {
		wait_usb_plugin(manager);
		printf("unmount_usb start\r\n");
		unmount_usb(manager);
		printf("unmount_usb end\r\n");

		if (mount_usb(manager) == 0) {

	            while(get_playback_flag())
	            {
	                printf("playback ing...\r\n");
	                sleep(1);
	            }

			printf("mount_usb OK\r\n");
			get_record_id(manager);
			change_led_mode(LED_DUMP);
			if (exe_update(manager) != 0) {

				get_config_info(manager);

				get_time(&(manager->time_export));
				set_disk_using(1);
				struct record_manager * record_manager = get_record_manager();
			    pthread_mutex_lock(&(record_manager->mutex_FileOpt));
			    {
				for (i = 0; i < 3; i++) {
					result = dump_data(manager, i);
					if (result != 0) {
						break;
					}
				}
			    }
			    pthread_mutex_unlock(&(record_manager->mutex_FileOpt));
				set_disk_using(0);
			}
			unmount_usb(manager);

			change_led_mode(LED_DUMP_FINISHED);
			wait_usb_plugout(manager);

			change_led_mode(LED_NORMAL);
		}

	}

	return NULL;
}

void * usbplugoutreset_proc(void * args) {

	char *device = NULL;
	while (1) {
		device = get_extern_device();
		if (device == NULL) {
			sleep(1);
			feedDog();
		} else {
			printf("usb plug in checked!\n");
			break;
		}
	}
	while (1) {
		device = get_extern_device();
		if (device == NULL) {
			printf("usb plug in checked!\n");
			system("reboot");
		} else {
			sleep(1);
			feedDog();
		}
	}

	return NULL;
}

static pthread_t thread_usbplugout_reset;

struct dump_manager* get_dump_manager() {
	if (gpdump_manager == NULL) {
		gpdump_manager = malloc(sizeof(struct dump_manager));
		if (gpdump_manager != NULL) {
			memset(gpdump_manager, 0, sizeof(struct dump_manager));

			add_block_filter(&(gpdump_manager->manager), NULL,
					sizeof(struct dump), 8);

			get_record_id(gpdump_manager);
			pthread_create(&(gpdump_manager->thread_dump), NULL, dump_proc,
					gpdump_manager);
			pthread_create(&(thread_usbplugout_reset), NULL,
					usbplugoutreset_proc,
					NULL);
		}
	}
	return gpdump_manager;
}

void start_dump() {

	get_dump_manager();

}

int send_dump(struct dump_manager *manager, int type, int num, char *data,
		int length) {
	struct block_filter * filter = manager->manager.fliters;

	struct block *pblock = get_block(filter, 10000, BLOCK_EMPTY); //usb存储慢得等下
	struct dump* dump = NULL;
	if (pblock != NULL) {
		dump = (struct dump*) pblock->data;
		dump->type = type;
		dump->length = length;
		dump->data_num = num;
		memcpy(dump->data, data, length);
		put_block(pblock, BLOCK_FULL);
		return 0;
	} else {
		printf("send_dump err\n");
		return -1;
	}
	return -1;

}

